import socketserver
import threading
from tuple_space import TupleSpace

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

class TupleHandler(socketserver.BaseRequestHandler):
    def handle(self):
        tuple_space = self.server.tuple_space
        tuple_space.stats['total_clients'] += 1
        while True:
            try:
                data = self.request.recv(1024).decode().strip()
                if not data:
                    break
                parts = data.split()
                if len(parts) < 3:
                    continue
                op, key = parts[1], parts[2]
                response = ""
                if op == 'P' and len(parts) >= 4:
                    response = tuple_space.put(key, ' '.join(parts[3:]))
                elif op == 'G':
                    response = tuple_space.get(key)
                elif op == 'R':
                    response = tuple_space.read(key)
                self.request.sendall(response.encode())
            except ConnectionResetError:
                break

def print_stats(tuple_space):
    while True:
        threading.Event().wait(10)
        stats = tuple_space.get_stats()
        print(
            f"[STATS] Tuples: {len(tuple_space.tuples)} | "
            f"Ops: {stats['total_ops']} (R:{stats['reads']} G:{stats['gets']} P:{stats['puts']}) | "
            f"Errors: {stats['errors']} | Clients: {stats['total_clients']}"
        )

if __name__ == "__main__":
    HOST, PORT = "localhost", 51234
    server = ThreadedTCPServer((HOST, PORT), TupleHandler)
    server.tuple_space = TupleSpace()
    stats_thread = threading.Thread(target=print_stats, args=(server.tuple_space,))
    stats_thread.daemon = True
    stats_thread.start()
    print(f"Server started on {HOST}:{PORT}")
    server.serve_forever()